home *** CD-ROM | disk | FTP | other *** search
- #include "MST_Defines.h"
- #include "MST_Externs.h"
- #include "MST_Prototypes.h"
-
-
- /*_____________________________________________________________________________
- Close_PeriodicChart()- close our Periodic Chart window
- _____________________________________________________________________________*/
-
-
- void Close_PeriodicChart ()
- {
- /*
- • See comments for Close_AboutMST() in the file About.c
- */
- if (PeriodicChartDlog==NIL) return;
- DisposDialog (PeriodicChartDlog);
- PeriodicChartDlog = NIL;
- }
-
-
- /*_____________________________________________________________________________
- Open_PeriodicChart()- create and display our Periodic Chart window
- _____________________________________________________________________________*/
-
-
- void Open_PeriodicChart ()
- {
- /*
- • See comments for Open_AboutMST() in the file About.c.
- */
- if (PeriodicChartDlog!=NIL) { SelectWindow (PeriodicChartDlog); return; }
-
- PeriodicChartDlog = GetNewDialog (ResID_PeriodicChart, NIL, (WindowPtr)-1);
-
- ShowWindow (PeriodicChartDlog);
- }
-
-
- /*_____________________________________________________________________________
- Update_PeriodicChart()- update our Periodic Chart window
- _____________________________________________________________________________*/
-
-
- void UpDate_PeriodicChart()
- {
- GDHandle saveDevice;
- CGrafPtr saveCGrafPtr;
- int loop1;
- Str255 thisString;
-
- if (PeriodicChartDlog==NIL) return; /*Make sure the periodic chart window exists*/
- /*
- • Now save the current Grafport and set the current port to our Periodic Chart window.
- */
-
- GetGWorld (&saveCGrafPtr,&saveDevice);
- SetGWorld ((CGrafPtr)PeriodicChartDlog,saveDevice);
- /*
- • Now we begin updating. You MUST call BeginUpdate() just before
- • and EndUpdate() just after doing your drawing. These two calls
- • restrict your drawing to just that portion of the window that
- • needs updating, and resets the window's update region to empty,
- • thus clearing the window's update event.
- •
- • Note: Dialogs, which are merely windows with a little more data added
- • to their struct, actually have their own routines for handling
- • updates, activate events, etc. Which ones are available depends
- • upon the type of dialog (alert, modal, or modeless). Here we treat
- • dialogs just like windows.
- */
-
- BeginUpdate (PeriodicChartDlog);
- /*
- • Here we set the port's pen colors. A more sophisticated program would examine
- • the operating system version upon initialization and adapt itself to the
- • operating systems capabilities (color Quickdraw might not be available, for
- • example. The program would also survey the available monitors upon initialization,
- • and adjust itself accordingly. For example, the program would not attempt to
- • draw in Light Blue on a monochrome monitor, as it will not show up.
- •
- • If you intend to run this on a monochrome monitor, just substitute Color_Black
- • for every instance of Color_LtBlue in this update routine.
- */
- RGBForeColor (&Color_LtBlue); /*Set the port's pen colors*/
- RGBBackColor (&Color_White);
- /*
- • Draw our decorative dotted line around the chart
- */
- for (loop1=13;loop1<=PeriodicChartDlog->portRect.right-13;loop1+=2)
- {
- MoveTo (loop1,PeriodicChartDlog->portRect.top+13);
- Line (0,0);
-
- MoveTo (loop1,PeriodicChartDlog->portRect.bottom-13);
- Line (0,0);
- }
- for (loop1=13;loop1<=PeriodicChartDlog->portRect.bottom-13;loop1+=2)
- {
- MoveTo (PeriodicChartDlog->portRect.left+13, loop1);
- Line (0,0);
-
- MoveTo (PeriodicChartDlog->portRect.right-13, loop1);
- Line (0,0);
- }
- /*
- • Since our program isn't sophisticated enough to allow user selection of fonts,
- • we had better pick one we can rely on being present. That restricts us to
- • Chicago, Geneva, or Monoco.
- */
- TextFont (geneva);
- TextSize (9);
- /*
- • And now we draw each box and write the symbol in it. We've already calculated
- • the rectangles for the boxes, and we have stored the element symbols in a
- • STR# resource. FrameRect draws the rectangle using the current pen. The MoveTo
- • and Move lines just calculate where to position the pen to start writing the
- • element's symbol. The Toolbox call DrawString actually writes the text using
- • the current font, color, etc. Remember, the color, pen size, font, & etc are
- • all properties of the current port. Most QuickDraw commands such as FrameRect,
- • MoveTo, DrawString, & etc operate implicitly on the current port with the
- • current port's settings.
- */
- for (loop1=1;loop1<=Max_NumElements;loop1++)
- {
- RGBForeColor (&Color_LtBlue);
- FrameRect (&PeriodicRects[loop1]);
- RGBForeColor (&Color_Black);
- GetIndString (thisString,ChemSymbsStr,loop1);
- MoveTo ((PeriodicRects[loop1].left)/2+(PeriodicRects[loop1].right) /2,
- (PeriodicRects[loop1].top) /2+(PeriodicRects[loop1].bottom)/2);
- Move (-StringWidth(thisString)/2,5);
- DrawString (thisString);
- }
- /*
- • Now we set the port's properties to a few defaults before we leave. In more
- • complex applications, with multiple fonts drawn into a single port, this
- • practice could save us some headaches in tracking down text drawing problems.
- • An alternative is to get various port attributes at the beginning of the
- • update, save them, and then restore them at the end of the update.
- */
- RGBForeColor (&Color_Black);
- TextFont (systemFont);
- TextSize (12);
-
- /*
- • Now finish up by balancing with a call to EndUpdate(), and restore
- • Quickdraw's pointer to the current Grafport to whatever it was
- • before you updated.
- */
-
- EndUpdate (PeriodicChartDlog);
-
- SetGWorld (saveCGrafPtr,saveDevice);
- }
-
-
- /*_____________________________________________________________________________
- Do_PeriodicChart()- handle an event in the content region
- of our Periodic Chart window
- _____________________________________________________________________________*/
-
-
- void Do_PeriodicChart (EventRecord *thisEvent)
- {
- long testKey,keyCode,loop1;
- /*
- • We convert the coordinates of the event to local window coordinates, and
- • check to see which element's rectangle, if any, the mousedown was in.
- • If it is a double click, we then open the appropriate element window.
- • Note that handling keyboard events has been broken out into a separate
- • function, Do_Key(), in the file WindowControl.c. In Listing 5 in the
- • original article of Do_PeriodicChart, we handled both mouse and keyboard
- • events in the Do_PeriodicChart function. This resulted in the program
- • inquiring whether an event was a mouse event or keyboard event twice:
- • once in the main event loop, and once in the Do_PeriodicChart function.
- • Handling keyboard events in a separate function is a better arrangement.
- */
-
- PeriodicChartWhere = thisEvent->where;
- GlobalToLocal (&PeriodicChartWhere);
-
- for (loop1=1;loop1<=Max_NumElements;loop1++)
- {
- if (PtInRect(PeriodicChartWhere,&PeriodicRects[loop1])==TRUE)
- {
- if (WaitDoubleClick(&PeriodicRects[loop1])==Click_Double) Open_Elements (loop1);
- return;
- }
- }
- }
-
-
- /*_____________________________________________________________________________
- WaitDoubleClick()- detect double clicks vs single clicks
- _____________________________________________________________________________*/
-
-
- int WaitDoubleClick (Rect *inHere)
- {
- Point thisPoint,savePoint;
- EventRecord thisEvent;
- long clickTime;
- /*
- • As we academics say, commenting this function is left as an exercise
- • for the reader.
- */
- while (EventAvail(mDownMask,&thisEvent)==TRUE) GetNextEvent(mDownMask,&thisEvent);
-
- while (StillDown()==TRUE)
- {
- GetMouse (&thisPoint);
- }
- if (EventAvail(mUpMask,&thisEvent)==TRUE) GetNextEvent(mUpMask,&thisEvent);
- savePoint = thisEvent.where;
- GlobalToLocal (&savePoint);
- clickTime = thisEvent.when + GetDblTime();
- while ((TickCount()<=clickTime) && (EventAvail(mDownMask,&thisEvent)!=TRUE)) {}
- if (TickCount()>clickTime)
- {
- if (PtInRect(savePoint,inHere)==TRUE) return Click_Single;
- else return Click_None;
- }
- GetNextEvent(mDownMask,&thisEvent);
- thisPoint = thisEvent.where;
- GlobalToLocal (&thisPoint);
- if (PtInRect(thisPoint,inHere)==TRUE)
- {
- while (StillDown()==TRUE) {}
- return Click_Double;
- }
- return Click_None;
- }
-